package org.xqh.test.yzs.mqtt;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.util.StringUtils;

import java.util.Scanner;

@Slf4j
public class EmqxClient {

//    public static final String HOST = "tcp://192.168.3.138:1883";// emqx server
//    public static final String HOST = "tcp://120.232.63.149:1883";// emqx server
//    public static final String HOST = "tcp://mqtt-test.ugreengroup.com:8883";// emqx server
    public static final String HOST = "tcp://mqtt-test.ugreengroup.com:1883";// emqx server

    public static final String TOPIC = "$test/";// 默认订阅topic

//    private static final String DEFAULT_USERNAME = "UG549HH11220F122";//默认UserName
    private static final String DEFAULT_USERNAME = "DH00002006000270";//默认UserName
//    private static final String DEFAULT_USERNAME = "UG554JJ18220FA86";//默认UserName
//    private static final String DEFAULT_PWD = "4qk7a9fnp07e535q";//默认密码
//    private static final String DEFAULT_PWD_SALT = "QR65mXeJ";




//    private static final String DEFAULT_PWD_SALT = "clouduser2";
    private static final String DEFAULT_PWD_SALT = "!@#123";
//private static final String DEFAULT_PWD = "Lgqbwm99PO0jE05K";//默认密码

//    private static final String DEFAULT_PWD = "ugreen123";//默认密码
    private static final String DEFAULT_PWD = "4vxviwnrzb32jcsk";//默认密码


    private MqttClient client;

    private MqttConnectOptions options;

    public MqttClient getClient(){
        return client;
    }

    private boolean will;

    private String willMsg;

    private int qos;

    private String pubTopic;

    private String clientId;

    private String pwd;

    private String userName;

    private boolean retain;

    private boolean isSub;

    private boolean cleanSession;

    private static final String DEFAULT_TOPIC = "nas/test/sub/topic";

    public static MqttClient getMqttClient(String clientId) {

        try {
            return new MqttClient(HOST, clientId, new MemoryPersistence());
        } catch (MqttException e) {
            e.printStackTrace();
        }

        return null;

    }

    public static MqttConnectOptions getOptions(boolean cleanSession,
                                                int connectTimeout,
                                                int keepAliveInterval,
                                                String userName,
                                                String password) {
        MqttConnectOptions options = new MqttConnectOptions();

        options.setUserName(userName);
        if (StringUtils.hasText(password)) {
            options.setPassword(password.toCharArray());
        }
        // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，这里设置为true表示每次连接到服务器都以新的身份连接
        options.setCleanSession(cleanSession);
        // 设置超时时间 单位为秒
        options.setConnectionTimeout(connectTimeout);
        // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
        options.setKeepAliveInterval(keepAliveInterval);
        return options;
    }

    /**
     * 发布消息
     * @param msg
     */
    public void publishMsg(String msg){
        MqttMessage message = new MqttMessage();
        message.setQos(qos);
        message.setRetained(retain);
        message.setPayload(msg.getBytes());
        MqttTopic mqttTopic = client.getTopic(pubTopic);
        MqttDeliveryToken token = null;
        try {
            token = mqttTopic.publish(message);
            token.waitForCompletion();
            String printMsg = String.format("publish msg: %s, topic: %s", msg, pubTopic);
//            log.info("发布消息success, topic==>{}, msg==>{}", pubTopic, msg);
            System.out.println(printMsg);
        } catch (MqttException e) {
            log.error("发布消息失败, topic==>{}, msg==>{}", pubTopic, msg, e);
        }
    }

    public void publishMsgScanner(){
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入publish内容：");
        System.out.println(help.toString());
        while (scanner.hasNext()){
            publishMsg(scanner.next());
        }
    }

    public void subscribeTopic(){
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入订阅topic：");
        System.out.println(help.toString());
        while (scanner.hasNext()){
            defaultSub(scanner.next());
        }
    }

    public void defaultSub(String topic){
        //订阅消息
        int[] Qos  = {qos};
        String[] topic1 = {topic};
        try {
            client.subscribe(topic1, Qos);
        } catch (MqttException e) {
            log.error("", e);
        }
    }


    public void start() {
        try {
            // host为主机名，clientid即连接MQTT的客户端ID，一般以唯一标识符表示，MemoryPersistence设置clientid的保存形式，默认为以内存保存
            client = getMqttClient(clientId);
            // MQTT的连接设置
            options = getOptions(cleanSession, 10, 20, userName, pwd);
            // 设置回调
            client.setCallback(new MqttOptCallback(client, options, isSub));
            String willTopic = StringUtils.isEmpty(pubTopic) ? DEFAULT_TOPIC : pubTopic;
//            if(StringUtils.isEmpty(willTopic)){
//                willTopic = TOPIC + "/will";
//            }
            MqttTopic topic = client.getTopic(willTopic);
            if(will){
                //setWill方法，如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
                options.setWill(topic, willMsg.getBytes(), 1, false);
            }
            client.connect(options);

        } catch (Exception e) {
            log.error("emqx client start err.", e);
        }
    }

    public EmqxClient(boolean will, String willMsg, int qos){
        this.will = will;
        this.willMsg = willMsg;
        this.qos = qos;
    }

    public EmqxClient(boolean will, String willMsg){
        this.will = will;
        this.willMsg = willMsg;
        this.qos = 2;//默认为1
    }

    public EmqxClient(){
        setDefaultProperty();
    }

    public EmqxClient(String clientId){
        setDefaultProperty();
        this.clientId = clientId;
    }

    public EmqxClient(String clientId, String pubTopic, boolean retain){
        setDefaultProperty();
        this.retain = retain;
        this.clientId = clientId;
        this.pubTopic = pubTopic;
    }

    public EmqxClient(String clientId, String pubTopic){
        setDefaultProperty();
        this.retain = true;
        this.will = true;
        this.clientId = clientId;
        this.pubTopic = pubTopic;
    }

    public void setSub(boolean sub) {
        isSub = sub;
    }

    public void setQos(int qos) {
        this.qos = qos;
    }

    public void setPubTopic(String pubTopic) {
        this.pubTopic = pubTopic;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public void setRetain(boolean retain) {
        this.retain = retain;
    }

    public void setDefaultProperty(){
        this.will = true;
        this.willMsg = "close";
        this.qos = 2;
        this.userName = DEFAULT_USERNAME;
        this.pwd = DEFAULT_PWD;
    }

    public void setUserName(String userName){
        this.userName = userName;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public void setCleanSession(boolean cleanSession) {
        this.cleanSession = cleanSession;
    }


}